/**
    webpack ^2.0

    入口文件中如若引用 require(*.css) 或 import '*.css', 则会被单独打包成一个 vendor.css 文件

    集合配置，适合单、多页面打包
*/

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');               //生成html文件
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require("extract-text-webpack-plugin");       // 打包生成 .css 文件
const CleanWebpackPlugin = require('clean-webpack-plugin');
const glob = require('glob');                                           //读取资源

/**********  配置开始  **********/

const _setting = {
    // 1. 入口文件
    // from: './src/健康体检/js/index.js',                     // 单页面打包
    from: './src/健康体检/js/*.js',                      // 多页面打包

    // 2. 打包后的项目路径
    dist: './dist/jktj',

    // 3. 依赖
    libs:
        // ['jquery'],
        // ['webpack-zepto'],
        ['webpack-zepto', 'fastclick'],
        // ['webpack-zepto', 'fastclick', 'better-picker'],
        // ['./src/健康百科/js/modules/WN.js'],
        // ['jquery','./src/jkda_PC/js/common/global.js','./src/jkda_PC/js/modules/post.js','./src/jkda_PC/js/modules/storage.js'],
        // ['webpack-zepto', 'fastclick','./src/jkda3_PHONE/js/modules/global.js','./src/jkda3_PHONE/js/modules/post.js','./src/jkda3_PHONE/js/modules/queryString.js','./src/jkda3_PHONE/js/modules/storage.js',],

    // 4. 是否启用 CDN 加速资源, 默认不使用 
    /*useCDN: {                           // 如果使用该项, _setting.libs 项目(可不注释)将不会打包进 vendor.js 内, 打包的体积因少了依赖库而减小
        'webpack-zepto': 'Zepto',       // 若文件中引用了 require('webpack-zepto') 时将会使用 window.Zepto 代替
        'fastclick': 'FastClick',
        'jquery': 'jQuery',
    },*/

    // 5. Autoprefixer 配置. last n version 是从IE 11开始的, 如果需要兼容IE 8为 last 4 version
    prefix: {
        // browsers: ['last 4 version', 'iOS >= 9', "Android >= 4.4"]
        browsers: ['iOS >= 9', "Android >= 4.4"]
        // browsers: ['last 1 version']
    },

    // 6. 是否将小于 8K 图片转 base64
    base64: true,

    // 7. 是否开启版本监听(仅多页面打包是可选). 开启后将多生成一个 manifest.js 文件, 使以后无论什么时候打包, 都只会更改有变动都文件都版本号
    manifest: false,

    // 8. 是否丢弃所有都 console 调试代码
    dropConsole: false,

    // 9. 是否在所有的 html 文件内自动添加 icon
    // favicon: './src/项目/favicon.ico',
};

/********** 配置结束 **********/

// 判断是否为多页面打包
const isMulty = /\*\.js/.test(_setting.from);

// 匹配项目名称
const projectName = _setting.from.match(/src\/(.+)\/js/)[1]; //例, A 或 A/A1 或 A/A1/A2 或 ...

// 若为单页面打包, 入口文件名称
let jsName;

// 匹配输出的项目名称
const distName = _setting.dist.match(/dist\/(.+)/)[1]; //例, A 或 A/A1 或 A/A1/A2 或 ...

Object.assign(_setting, {
    build: {// 生成的文件保存路径, 相对于 _setting.build.publicPath
        publicPath: '/'+ distName +'/',                     // 绝对路径,最后的 '/' 必须, 否则图片路径不能正确指引
        jsPath: 'js/[name].[chunkhash:8].js',
        cssPath: 'css/[name].[contenthash:8].css',
        imgPath: 'img/[hash:8].[ext]',                      // 如果有大量共同的 图片, 可使用 '../static/[hash:8].[ext]' 生成图片目录与该项目目录同级
    }
});

// 所有的入口文件(含依赖)
const entry = (function(){
    let entries = {};

    // 如果是单页面, 不应添加 entties.vendor, 因为会多生成一个 vendor.js 文件
    if ( isMulty && _setting.libs.length ) {
        entries.vendor = _setting.libs;
    };

    glob.sync( _setting.from ).forEach( item => {
        let name = item.match(/([\w\-]+)\.js$/)[1];                     //匹配文件名

        if ( !isMulty ) {
            jsName = name;
        }

        entries[name] = [item];                                         //单元素数组
    });

    console.log(entries);

    return entries;
})();

const WEBPACK_MODULE = {
    entry: entry,
    output: {
        path: path.resolve(__dirname, _setting.dist ),
        publicPath: _setting.build.publicPath,//chunkHash将配合manifest.js,使未改动的文件(一般是第三方库、图片等)在打包的时候也不改变hash
        filename: _setting.build.jsPath,
    },
    externals: _setting.useCDN,
    module: {
        rules: [
            // { test: /\.less$/, loader: 'style-loader!css-loader!postcss-loader!less-loader' },//不单独提取.css文件时使用
            { test: /\.js$/, exclude: /node_modules/, use: 'babel-loader'},
            { test: /\.(less|css)$/, use: ExtractTextPlugin.extract(['css-loader', 'postcss-loader', 'less-loader']) },
            { test: /\.(jpg|png|gif)$/i, use: ( _setting.base64 ? 'url-loader?limit=8192&name=' : 'file-loader?name=' ) + _setting.build.imgPath }, // url-loader是file-loader的加强版. 不支持ico格式.css部分背景图片的路径及文件名
            { test: /\.html$/, use: "html-withimg-loader?min=true" }//处理 html 的图片路径并支持#include语法
        ]
    },
    plugins: [
        new CleanWebpackPlugin(new Array( _setting.dist )), //删除打包文件存放的目录内的旧文件

        new webpack.DefinePlugin({
            'process.env': { NODE_ENV: '"production"' }
        }),
        
        /*
        // 作用: 项目内不再需要显式声明 import $ from 'jquery' 或 const $ = require('jquery')
        new webpack.ProvidePlugin({
            jQuery: "jquery",
            $: "jquery",
            Vue: "vue"
        }),*/

        // 所有文件的共用模块. 单页面的共用模块即为自身
        new webpack.optimize.CommonsChunkPlugin({ //配合 vendor 生成 manifest.js 及 vendor.js
            names: isMulty ? ( _setting.manifest ? ['vendor', 'manifest'] : ['vendor'] ) : [jsName]
        }),

        new webpack.LoaderOptionsPlugin({ //webpack2写法上的差异
            options: { postcss: [autoprefixer( _setting.prefix )] }
        }),

        new ExtractTextPlugin( _setting.build.cssPath ), //生成的css路径及文件名

        new webpack.optimize.UglifyJsPlugin({
            minimize: true, 
            compress: {
                warnings: false,
                drop_console: _setting.dropConsole,
                drop_debugger: true
            },
            /*mangle: {
                // 跳过这些
                except: ['$super', '$', 'exports', 'require']
            }*/
        })
    ],
    performance: {
        hints: false
    }
};

/* 生成html文件 */
Object.keys(entry).forEach(name => {
    if (name == 'vendor') {//遍历到 vendor 退出当前循环,并进行下一循环
        return;
    }
    let config = {
        template: './src/' + projectName + '/' + name +'.html',
        filename: name +'.html',
        chunks: ['manifest', 'vendor', name],//必须限定, 否则每个打包后的html都会加载所有打包后的js(如果有 manifest.js 文件时会自动引入, 否则不引入)
        hash: false, //形如: xxx.js?[hash]
        inject: 'body',
        minify: {
            removeComments: true,
            collapseWhitespace: true
        }
    };

    if (_setting.favicon) {
        config.favicon = _setting.favicon;
    }

    WEBPACK_MODULE.plugins.push(new HtmlWebpackPlugin(config));
});

module.exports = WEBPACK_MODULE;